package br.com.itc.componentes.campoPesquisa {
	
	import br.com.itc.componentes.botoes.BotaoProcurarView;
	import br.com.itc.componentes.containers.CanvasITC;
	import br.com.itc.componentes.dto.SelGeralReqDto;
	import br.com.itc.componentes.evento.SelGeralEvento;
	import br.com.itc.componentes.input.Rotulo;
	import br.com.itc.componentes.input.Texto;
	import br.com.itc.componentes.modulos.DataGridITC;
	import br.com.itc.componentes.util.PopUpUtil;
	import br.com.itc.componentes.util.ReflectionUtil;
	import br.com.itc.componentes.util.servico.ServicoJava;
	import br.com.itc.componentes.util.servico.ServicoJavaUtil;
	
	import flash.display.DisplayObject;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.ui.Keyboard;
	
	import mx.core.Application;
	import mx.events.CloseEvent;
	import mx.events.FlexEvent;
	import mx.managers.PopUpManager;
	import mx.rpc.events.ResultEvent;
	import mx.utils.StringUtil;

	/**
	 * Classe que implementa o comportamento do campo de pesquisa.
	 *
	 */
	public class CampoPesquisa extends CanvasITC {

		private var _txtValor: Texto;

		private var _btnProcurar: BotaoProcurarView;

		private var _lblDescricao: Rotulo;

		private var _janela : PesquisaGeral;

		private var _metodoPesquisa: String = "pesquisarPorCodigo";

		private var _servicoPesquisa: ServicoJava;
		
		private var _funcaoCriacaoDto: Function;

		private var _validarObrigatorio : Boolean;

		private var _larguraJanela: int = 600;
		
		private var _alturaJanela: int = 420;
		
		private var _titulo: String;

		private var _exibirCampoCodigo: Boolean = true;

		private var _painelLista: CanvasITC;
		
		private var _destino:String;

		private var _objetoSelecionado: Object;

		private var _campoCodigo: String;
		private var _campoDescricao: String;
		
		private var _tabela: DataGridITC;

		public function CampoPesquisa():void {
			this.addEventListener(FlexEvent.CREATION_COMPLETE, init);
		}

		public function init(event:FlexEvent):void {
			this.btnProcurar.addEventListener(MouseEvent.CLICK, botaoProcurarPressionado);
			this.txtValor.addEventListener(FocusEvent.FOCUS_OUT, blurCampoValor);
		}

		public function botaoProcurarPressionado(event: MouseEvent):void {
			event.stopPropagation();
			abrirJanelaPesquisa();
		}
		
		public function blurCampoValor(event:FocusEvent):void {
			if (StringUtil.trim(txtValor.text).length == 0 || StringUtil.trim(txtValor.text) == "0") {
				limparSelecao();
			} else if (objetoSelecionado == null || 
				(objetoSelecionado != null && recuperarCampoCodigo() != StringUtil.trim(txtValor.text))) {
				pesquisar();
			}
		}

		public function janelaFechada(event:CloseEvent):void {
			fecharJanelaPesquisa();
		}

		public function functionobjetoSelecionado(event: SelGeralEvento):void {
			objetoSelecionado = event.objetoSelecionado;
			atualizarCampos();
			fecharJanelaPesquisa();
			notificarSelecao();
		}

		
		
		protected function teclaPressioanda(event: KeyboardEvent):void {
			if (event.keyCode == Keyboard.ESCAPE) {
				fecharJanelaPesquisa();
				event.stopPropagation();
			}
		}
		
		protected function botaoOkPressionado(event: MouseEvent): void {
			objetoSelecionado = tabela.selecionarItem();
			if (objetoSelecionado != null) {
				atualizarCampos();
				notificarSelecao();
				fecharJanelaPesquisa();
			}
		}

		protected function botaoFecharPressionado(event: MouseEvent): void {
			fecharJanelaPesquisa();
		}

		public function validar(): Boolean {
			return txtValor.isValido();
		}

		public function pesquisar():void {
			procurar(txtValor.text);
		}

		public function procurar(valor:String):void {
			if (destino != null) {
				ServicoJavaUtil.getServico(metodoPesquisa, destino, pesquisaRealizada).getOperation(metodoPesquisa).send(criarCriterios(valor));
			}
		}
		
		protected function criarCriterios(valor: String): SelGeralReqDto {
			var dto: SelGeralReqDto = new SelGeralReqDto;
			
			var criterios: Object = null;

			if (funcaoCriacaoDto == null) {
				criterios = valor;
			} else {
				criterios = funcaoCriacaoDto(valor);
			}
			
			dto.dados.filtro = criterios;
			return dto;
		}

		public function pesquisaRealizada(event : ResultEvent) : void {
			if (event.result.dados.lista != null && event.result.dados.lista.length > 0) {
				objetoSelecionado = event.result.dados.lista[0];
				atualizarCampos();
				notificarSelecao();
			} else {
				limparSelecao();
			}
		}

		public function limparSelecao():void {
			objetoSelecionado = null;
			atualizarCampos();
			notificarSelecao();
		}

		protected function abrirJanelaPesquisa():void {
			_janela = new PesquisaGeral;
			_janela.width = _larguraJanela;
			_janela.height = _alturaJanela;
			_janela.title = _titulo;
			_janela.addEventListener(CloseEvent.CLOSE, janelaFechada);
			_janela.addEventListener(KeyboardEvent.KEY_DOWN, teclaPressioanda, true);

			painelLista.percentWidth = 100;
			painelLista.percentHeight = 100;

			_janela.addChild(painelLista);
			
			PopUpManager.addPopUp(_janela, Application.application as DisplayObject, true);
			PopUpManager.centerPopUp(_janela);
			
			_janela.btnOK.addEventListener(MouseEvent.CLICK, botaoOkPressionado);
			_janela.btnFechar.addEventListener(MouseEvent.CLICK, botaoFecharPressionado);
		}

		protected function fecharJanelaPesquisa(): void {
			PopUpUtil.fecharJanela(_janela);
		}

		protected function atualizarCampos(): void {
			if (objetoSelecionado != null) {
				this.lblDescricao.text = formatarDescricao(recuperarCampoDescricao());
				this.txtValor.text = formatarDescricao(recuperarCampoCodigo());
			} else { 
				this.lblDescricao.text = "";
				this.txtValor.text = "";
			}
		}

		protected function formatarDescricao(descricao: String): String {
			var texto:String = descricao;
			var tamanhoDisponivel:int = this.width - (txtValor.width + btnProcurar.width + 20); 

			if (texto != null) {

				while (lblDescricao.measureText(texto).width >= tamanhoDisponivel && texto.length > 0) {
					texto = texto.substring(0, texto.length - 1);
				}
			}

			return texto;
		}		
		
		protected function notificarSelecao():void {
			var evento: SelGeralEvento = new SelGeralEvento(SelGeralEvento.OBJETO_SELECIONADO);
			evento.objetoSelecionado = this.objetoSelecionado;
			this.dispatchEvent(evento);
		}

        public function set txtValor(value: Texto):void {
            _txtValor = value;
        }

        public function get txtValor(): Texto {
            return _txtValor;
        }

        public function set btnProcurar(value: BotaoProcurarView):void {
            _btnProcurar = value;
        }

        public function get btnProcurar(): BotaoProcurarView {
            return _btnProcurar;
        }

        public function set lblDescricao(value: Rotulo):void {
            _lblDescricao = value;
        }

        public function get lblDescricao(): Rotulo {
            return _lblDescricao;
        }

		[Bindable]
		public function set destino(value:String):void {
            _destino = value;
        }

        public function get destino():String {
            return _destino;
        }

		public function set painelLista(value: CanvasITC):void {
            _painelLista = value;

            if (_painelLista != null) {
            	_painelLista.addEventListener(SelGeralEvento.OBJETO_SELECIONADO, functionobjetoSelecionado);
            }
        }
       
		public function get painelLista(): CanvasITC {
            return _painelLista;
        }

        public function set larguraJanela(value:int):void {
            _larguraJanela = value;
        }

        public function get larguraJanela():int {
            return _larguraJanela;
        }

        public function set alturaJanela(value:int):void {
            _alturaJanela = value;
        }

        public function get alturaJanela():int {
            return _alturaJanela;
        }

        public function set titulo(value:String):void {
            _titulo = value;
        }

        public function get titulo():String {
            return _titulo;
        }

        public function set exibirCampoCodigo(value:Boolean):void {
            _exibirCampoCodigo = value;
        }

        [Bindable]
        [Inspectable(category="Common")]
        public function get exibirCampoCodigo():Boolean {
            return _exibirCampoCodigo;
        }

        public function set validarObrigatorio(value:Boolean):void {
            _validarObrigatorio = value;
        }
		
        [Bindable]
        [Inspectable(category="Common")]
        public function get validarObrigatorio():Boolean {
            return _validarObrigatorio;
        }

        public function set metodoPesquisa(value: String):void {
            _metodoPesquisa = value;
        }

        public function get metodoPesquisa(): String {
            return _metodoPesquisa;
        }

		public function set campoCodigo(value: String):void {
            _campoCodigo = value;
        }

        public function get campoCodigo(): String {
            return _campoCodigo;
        }

		public function set campoDescricao(value: String):void {
            _campoDescricao = value;
        }

        public function get campoDescricao(): String {
            return _campoDescricao;
        }

        public function set objetoSelecionado(value: Object):void {
            _objetoSelecionado = value;
        }

        public function get objetoSelecionado(): Object {
            return _objetoSelecionado;
        }
        
    	public function set funcaoCriacaoDto(value: Function): void {
            _funcaoCriacaoDto = value;
        }

        public function get funcaoCriacaoDto(): Function {
            return _funcaoCriacaoDto;
        }
        
        public function set tabela(value: DataGridITC):void {
            _tabela = value;
        }
        
        [Bindable]
        public function get tabela(): DataGridITC {
            return _tabela;
        }
        
        private function recuperarCampoCodigo(): String {
        	return ReflectionUtil.recuperarPropriedade(objetoSelecionado, campoCodigo) as String;
        }

        private function recuperarCampoDescricao(): String {
        	return ReflectionUtil.recuperarPropriedade(objetoSelecionado, campoDescricao) as String;
        }
	}
}